package com.zhangkeyou.map.mapweb.service;

import com.alibaba.fastjson.JSONObject;
import com.zhangkeyou.map.mapweb.domain.entity.Article;
import com.zhangkeyou.map.mapweb.domain.entity.LoginUser;
import com.zhangkeyou.map.mapweb.exception.DefinitionException;
import com.zhangkeyou.map.mapweb.mapper.ArticleMapper;
import com.zhangkeyou.map.mapweb.mapper.UserinfoMapper;
import com.zhangkeyou.map.mapweb.util.MyUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;

@Service
@Slf4j
public class ArticleService {
    @Autowired
    private ArticleMapper articleMapper;
    @Autowired
    private UserinfoMapper userinfoMapper;

    @Autowired
    FileService fileService;


    /**
     * 返回articleList，如果title为空则删除
     * @return
     */
    public List<Article> getArticleList(){
        LoginUser loginUser = (LoginUser) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
        String userId = loginUser.getUserinfo().getId();
        List<Article> articles = articleMapper.selectArticleListByUserinfoId(userId);
        List<Article> articleNotNull = articles.stream().filter(article -> {
            if (Objects.isNull(article.getTitle())) {
                deleteByWangEditor(article.getId());
                log.debug("文章没有题目，已删除：id为"+article.getId());
                return false;
            } else {
                return true;
            }
        }).collect(Collectors.toList());
        return articleNotNull;
    }

    public Article getArticleInformation(String id) {
        Article article = articleMapper.selectById(id);
        if(Objects.isNull(article))
            throw new DefinitionException(403,"未查到数据");
        return article;
    }


    /**
     *
     * @param article
     * @return 需要修改article_id的file
     */
    public JSONObject insertArticleFromCkeditor5(Article article) {
        LoginUser loginUser = (LoginUser) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
        if(Objects.isNull(loginUser))
            throw new RuntimeException("未登录");
        String userId = loginUser.getUserinfo().getId();

        //新增文章
        String articleId = UUID.randomUUID().toString();
        article.setId(articleId);
        article.setUserinfoid(userId);

        Integer insert = articleMapper.insert(article);
        List<String> fileIdList = extractImageIdList(article.getArticle());
        if(fileIdList!=null){
            fileIdList.forEach(fileId->{
                fileService.setArticleId(fileId,articleId);
            });
        }
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("插入文章数量",insert);
        jsonObject.put("文章图片数量",fileIdList.size());
        jsonObject.put("id",articleId);
        return jsonObject;
    }

    /**
     *
     * @param article
     * @return 返回现在存在的图片idList
     */
    public JSONObject updateArticleFromCkeditor5(Article article) {
        LoginUser loginUser = (LoginUser) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
        String userId = loginUser.getUserinfo().getId();

        //修改文章
        String articleId = article.getId();
        //文档中的文件
        int count = articleMapper.updateByIdUserinfoid(article);
        if(count==0){
            throw new DefinitionException(403,"文章未知");
        }

        List<String> imageListInArticle = extractImageIdList(article.getArticle());
        //数据库中保存的文件
        List<String> imageListInDatabase = fileService.getFileIdListByArticleId(articleId);
        AtomicInteger newImageCount = new AtomicInteger();
        AtomicInteger deleteImageCount= new AtomicInteger();
        imageListInArticle.forEach(imageId->{
            if(!imageListInDatabase.contains(imageId)){
                // 文件已经上传的服务器，但没有在数据库中标识article_id字段
                newImageCount.getAndIncrement();
                log.debug(String.format("设置文件Id为%s的文件articleId为%s",imageId,articleId));
                fileService.setArticleId(imageId,articleId);
            }
        });
        imageListInDatabase.forEach(imageId->{
            if(!imageListInArticle.contains(imageId)){
                // 文件已经从文章中删除，需要删除文件
                deleteImageCount.getAndIncrement();
                log.debug(String.format("fileId:%s的照片被删除",imageId));
                fileService.deleteFile(imageId,userId, MyUtils.FileSource.ARTICLE);
            }
        });

        int time = fileService.deleteImageInNullArticle();
        log.info(String.format("id为%s的文章已经更新",article.getId()));

        JSONObject jsonObject = new JSONObject();
        jsonObject.put("删除图片数量",deleteImageCount);
        jsonObject.put("新增图片数量",newImageCount);
        jsonObject.put("id",article.getId());
        return jsonObject;
    }


    public JSONObject insertArticleFromWangEditor(Article article) {
        LoginUser loginUser = (LoginUser) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
        if(Objects.isNull(loginUser))
            throw new RuntimeException("未登录");
        String userId = loginUser.getUserinfo().getId();

        //新增文章
        String articleId = UUID.randomUUID().toString();
        article.setId(articleId);
        article.setUserinfoid(userId);

        Integer insert = articleMapper.insert(article);
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("data","插入成功");
        jsonObject.put("id",articleId);
        return jsonObject;
    }

    public JSONObject updateArticleFromWangEditor(Article article) {
        LoginUser loginUser = (LoginUser) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
        String userId = loginUser.getUserinfo().getId();

        //修改文章
        String articleId = article.getId();
        article.setUserinfoid(userId);
        //文档中的文件
        int count = articleMapper.updateByIdUserinfoid(article);
        if(count==0){
            throw new DefinitionException(403,"文章未知");
        }

        JSONObject jsonObject = new JSONObject();
        jsonObject.put("data","更新成功");
        return jsonObject;
    }
    /**
     * 返回
     * @param articleContent
     * @return
     */
    private List<String> extractImageIdList(String articleContent){
        List<String> articleImageIdList = new LinkedList<>();
        String pattern = "<img src=\"(\\S*)\"";
        Pattern compile = Pattern.compile(pattern);
        Matcher matcher = compile.matcher(articleContent);
        while(matcher.find()){
            String imageUrl = matcher.group(1);
            articleImageIdList.add(getImageId(imageUrl));
        }
        return articleImageIdList;
    }

    private String getImageId(String imageUrl){
        String pattern = "(\\?|\\&)" + "fileId" + "=([^\\&]+)";
        Pattern compile = Pattern.compile(pattern);
        Matcher matcher = compile.matcher(imageUrl);
        while(matcher.find()){
            return matcher.group(2);
        }
        return null;
    }

    public JSONObject deleteByCkEditor5(Article article) {
        JSONObject jsonObject = new JSONObject();

        LoginUser loginUser = (LoginUser) SecurityContextHolder.getContext().getAuthentication().getPrincipal();

        String userId = loginUser.getUserinfo().getId();
        article.setUserinfoid(userId);
        int count = articleMapper.deleteByIdUserinfoid(article.getId(),userId);
        jsonObject.put("删除文章数量",count);
        if(count>0){
            Integer deleteImageCount = fileService.deleteFileByArticleId(article);
            jsonObject.put("删除图片数量",deleteImageCount);
        }else{
            throw new DefinitionException(403,"未找到该文章");
        }
        return jsonObject;
    }

    public JSONObject deleteByWangEditor(String articleId) {
        LoginUser loginUser = (LoginUser) SecurityContextHolder.getContext().getAuthentication().getPrincipal();

        String userId = loginUser.getUserinfo().getId();

        int count = articleMapper.deleteByIdUserinfoid(articleId,userId);
        List<String> fileIdList = fileService.getFileIdListByArticleId(articleId);
        fileIdList.forEach(deletingFileId->{
            fileService.deleteFile(deletingFileId,userId, MyUtils.FileSource.ARTICLE);
        });
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("删除图片",fileIdList);
        return jsonObject;
    }

    public JSONObject setArticleId(String articleId, List<String> fileIdList) {
        fileIdList.forEach(fileId->{
            int count = articleMapper.updateArticleIdByFileId(articleId,fileId);
        });
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("data","success");
        return jsonObject;
    }

    public String getRandomArticleId() {
        LoginUser loginUser = (LoginUser) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
        String userId = loginUser.getUserinfo().getId();
        String id = UUID.randomUUID().toString();
        Article article = new Article();
        article.setUserinfoid(userId);
        article.setId(id);
        articleMapper.insert(article);
        return id;
    }

}
